// 16_args_test.rs
// Rust 泛型参数处理教程

use std::path::{Path, PathBuf};

/// 一个可以接收各种字符串类型参数的函数示例
/// 使用 AsRef trait 来接受 &str, String, &String 等类型
fn process_string_input<T: AsRef<str>>(input: T) -> String {
    let s = input.as_ref();
    format!("处理字符串: {}", s)
}

/// 一个可以接收各种路径类型参数的函数示例
/// 使用 AsRef<Path> 来接受 &Path, PathBuf, &PathBuf, &str, String 等类型
fn process_path_input<P: AsRef<Path>>(path: P) -> String {
    let p = path.as_ref();
    format!("处理路径: {:?}", p)
}

/// 更复杂的示例：同时处理字符串和路径参数
fn complex_function<S: AsRef<str>, P: AsRef<Path>>(name: S, path: P) -> String {
    let name_str = name.as_ref();
    let path_obj = path.as_ref();
    format!("名称: {}, 路径: {:?}", name_str, path_obj)
}

/// 使用 where 子句限制参数类型的示例
/// 这种语法在参数约束复杂时更加清晰
fn function_with_where_clause<S, P>(name: S, path: P) -> String
where
    S: AsRef<str>,
    P: AsRef<Path>,
{
    let name_str = name.as_ref();
    let path_obj = path.as_ref();
    format!("where子句 - 名称: {}, 路径: {:?}", name_str, path_obj)
}

/// 使用 where 子句的更复杂示例，添加额外的约束
fn advanced_function_with_where<S, P, T>(name: S, path: P, data: T) -> String
where
    S: AsRef<str> + std::fmt::Display,
    P: AsRef<Path>,
    T: std::fmt::Debug,
{
    let name_str = name.as_ref();
    let path_obj = path.as_ref();
    format!("高级where子句 - 名称: {}, 路径: {:?}, 数据: {:?}", name_str, path_obj, data)
}

/// 使用 impl Trait 语法的简化版本（Rust 2024 新特性）
fn process_string_impl(input: impl AsRef<str>) -> String {
    let s = input.as_ref();
    format!("impl Trait 处理字符串: {}", s)
}

fn process_path_impl(path: impl AsRef<Path>) -> String {
    let p = path.as_ref();
    format!("impl Trait 处理路径: {:?}", p)
}

fn main() {
    println!("=== 泛型参数处理教程 ===");
    
    // 1. 字符串参数处理
    println!("\n1. 字符串参数处理");
    
    // 可以接受 &str
    let result1 = process_string_input("hello");
    println!("{}", result1);
    
    // 可以接受 String
    let string_var = String::from("world");
    let result2 = process_string_input(string_var.clone());
    println!("{}", result2);
    
    // 可以接受 &String
    let result3 = process_string_input(&string_var);
    println!("{}", result3);
    
    // 使用 impl Trait 语法
    let result4 = process_string_impl("impl trait");
    println!("{}", result4);
    
    // 2. 路径参数处理
    println!("\n2. 路径参数处理");
    
    // 可以接受 &str 作为路径
    let result1 = process_path_input("path/to/file.txt");
    println!("{}", result1);
    
    // 可以接受 String 作为路径
    let path_string = String::from("another/path");
    let result2 = process_path_input(path_string);
    println!("{}", result2);
    
    // 可以接受 PathBuf
    let path_buf = PathBuf::from("path_buf_example");
    let result3 = process_path_input(path_buf.clone());
    println!("{}", result3);
    
    // 可以接受 &PathBuf
    let result4 = process_path_input(&path_buf);
    println!("{}", result4);
    
    // 可以接受 &Path
    let path_ref = Path::new("path_ref_example");
    let result5 = process_path_input(path_ref);
    println!("{}", result5);
    
    // 使用 impl Trait 语法
    let result6 = process_path_impl("impl_trait_path");
    println!("{}", result6);
    
    // 3. 复合函数示例
    println!("\n3. 复合函数示例");
    
    let name = "测试文件";
    let path = PathBuf::from("/home/user/documents");
    let result = complex_function(name, &path);
    println!("{}", result);
    
    let name_string = String::from("另一个文件");
    let result2 = complex_function(name_string, "/tmp/data");
    println!("{}", result2);
    
    // 4. 使用 where 子句的函数示例
    println!("\n4. 使用 where 子句的函数示例");
    
    let name = "where示例";
    let path = PathBuf::from("/example/path");
    let result = function_with_where_clause(name, &path);
    println!("{}", result);
    
    let name_string = String::from("高级where示例");
    let result2 = function_with_where_clause(name_string, "/advanced/path");
    println!("{}", result2);
    
    // 5. 高级 where 子句示例
    println!("\n5. 高级 where 子句示例");
    
    let name = "高级示例";
    let path = Path::new("/advanced/example");
    let data = vec![1, 2, 3];
    let result = advanced_function_with_where(name, path, data);
    println!("{}", result);
    
    println!("\n泛型参数处理教程完成！");
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_string_processing() {
        // 测试 &str
        assert_eq!(process_string_input("test"), "处理字符串: test");
        
        // 测试 String
        let s = String::from("owned string");
        assert_eq!(process_string_input(s), "处理字符串: owned string");
        
        // 测试 &String
        let s = String::from("borrowed string");
        assert_eq!(process_string_input(&s), "处理字符串: borrowed string");
    }
    
    #[test]
    fn test_path_processing() {
        // 测试 &str 作为路径
        assert_eq!(process_path_input("test/path"), "处理路径: \"test/path\"");
        
        // 测试 PathBuf
        let path_buf = PathBuf::from("path/buf");
        assert_eq!(process_path_input(path_buf), "处理路径: \"path/buf\"");
        
        // 测试 &Path
        let path = Path::new("test/path");
        assert_eq!(process_path_input(path), "处理路径: \"test/path\"");
    }
    
    #[test]
    fn test_complex_function() {
        let result = complex_function("name", "/path");
        assert!(result.contains("名称: name"));
        assert!(result.contains("路径:"));
    }
    
    #[test]
    fn test_where_clause_function() {
        let result = function_with_where_clause("test", "/test/path");
        assert!(result.contains("where子句 - 名称: test"));
        assert!(result.contains("路径:"));
    }
    
    #[test]
    fn test_advanced_where_function() {
        let result = advanced_function_with_where("advanced", Path::new("/advanced"), vec![1, 2, 3]);
        assert!(result.contains("高级where子句"));
        assert!(result.contains("advanced"));
    }
}